<?php
/**
 * prevent csrf attack
 *
 * @author tom.wang<tom.wang.sz@qq.com>
 *
 * @usage
 * if(isset($_REQUEST['sig'])) {
 * 		CsrfUtil::checkSign($_REQUEST['sig'], $_SESSION['sig']);
 * }
 * $sig = CsrfUtil::getSign();
 * $_SESSION['sig'] = $sig;
 * <input type="hidden" value="{$sig}" />
 */
class CsrfUtil {
	/**
	 * prevent construct
	 */
	private function __construct() {
		throw new CatException('Can not construct!');
	}
	
	/**
	 * generate a sign
	 *
	 * @return string
	 */
	public static function getSign() {
		$ip = self::getClientIp();
		$rand = mt_rand();
		
		return sha1($ip . $rand);
	}
	
	/**
	 * check sign(maybe $_POST and $_SESSION)
	 *
	 * @param string $sig1
	 * @param string $sig2
	 *
	 * @return bool
	 */
	public static function checkSign($sig1, $sig2) {
		$ret = false;
		# here should check empty
		if(!empty($sig1) && !empty($sig2) && $sig1 === $sig2) $ret = true;
		
		return $ret;
	}
	
	/**
	 * get client ip
	 *
	 * @return string
	 */
	protected static function getClientIp() {
		if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
			$onlineip = getenv('HTTP_CLIENT_IP');
		} elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
			$onlineip = getenv('HTTP_X_FORWARDED_FOR');
		} elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
			$onlineip = getenv('REMOTE_ADDR');
		} elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
			$onlineip = $_SERVER['REMOTE_ADDR'];
		}
		return preg_match("/[\d\.]{7,15}/", $onlineip, $matches) ? $matches[0] : 'unknown';
	}
}
?>